package com.yanqu.road.server.manager.cross.battle.dunhuangshiku;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSON;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.CrossActivityDetail;
import com.yanqu.road.entity.activity.dunhuangshiku.*;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eChatContentType;
import com.yanqu.road.entity.enums.eDunHuangShiKuEventType;
import com.yanqu.road.entity.log.cross.*;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.logic.bussiness.activity.DunHuangShiKuActivityBusiness;
import com.yanqu.road.logic.bussiness.player.activity.UserDunHuangShiKuActivityBusiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.dunhuangshiku.DunHuangShiKuProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description
 * @Author cwq
 * @Data 2021/4/15 17:53
 */
public class DunHuangShiKuActivity {

    public int activityId;

    public int groupId;

    /**
     * 队伍最大id
     */
    private AtomicInteger maxTeamId;

    /**
     * 玩家信息
     */
    public Map<Long, DunHuangShiKuUser> userMap = new ConcurrentHashMap<>();

    /**
     * 需要删除的队伍 （临时存放，入库后移除）
     */
    public List<DunHuangShiKuTeam> deleteList = new ArrayList<>();

    /**
     * 队伍集合 （不含解散的队伍） k:队伍id
     */
    public Map<Integer, DunHuangShiKuTeam> teamMap = new ConcurrentHashMap<>();

    /**
     * 队伍排名 （只包含有分数的队伍）
     */
    public List<DunHuangShiKuTeam> teamRankList = new ArrayList<>();

    /**
     * 更新分数次数 如果查看的时候 并且updateNum>0 要重新排序
     */
    private int updateNum = 0;

    /**
     * 队伍集合(按总赚钱排序) （不含解散的队伍）
     */
    public List<DunHuangShiKuTeam> teamList = new ArrayList<>();

    /**
     * 队伍集合 k:区服id v:队伍(按总赚钱排序)（不含解散的队伍）
     */
    public Map<Long, List<DunHuangShiKuTeam>> serverTeamsMap = new ConcurrentHashMap<>();

    /**
     * 莫高窟区域玩家集合
     */
    public List<DunHuangShiKuUser> region3UserList = new ArrayList<>();

    /**
     * 日志信息击杀流水
     */
    public List<DunHuangShiKuKillLogData> killLogList = new ArrayList<>();

    /**
     * 日志信息击杀流水 （临时存放，入库后移除）
     */
    private List<DunHuangShiKuKillLogData> killLogTempList = new ArrayList<>();

    /**
     * npc血量<k：npcId,v；DunHuangShiKuNpcBlood>
     */
    private Map<Integer, DunHuangShiKuNpcBloodData> npcBloodMap = new ConcurrentHashMap<>();

    /**
     * 所有活跃玩家数据 k:区服id  v：活跃玩家集合
     */
    private Map<Long, List<DunHuangShiKuUserBloodInfo>> allUserBloodMap = new ConcurrentHashMap<>();

    public RandomHelper random = new RandomHelper();

    public int DUNHUANGSHIKU_SCORE_ITEM_ID = 101964;        // 敦煌石窟积分道具ID
    public int DUNHUANGSHIKU_ENERGY_ITEM_ID = 120440;       // 敦煌石窟体力道具ID
    public int DUNHUANGSHIKU_CREATE_TEAM_TIME = 2040;              //敦煌石窟组队时长(分)
    public int DUNHUANGSHIKU_TEAM_NAME_LENGTH_LIMIT = 6;      //敦煌石窟队伍名字字数上限
    public int DUNHUANGSHIKU_CREATE_TEAM_NEED_INGOTS = 100;   //敦煌石窟创建队伍元宝消耗
    public int DUNHUANGSHIKU_ENERGY_CD = 1800;                //敦煌石窟体力CD时间（s）
    public int DUNHUANGSHIKU_ENERGY_CD_NUM = 5;               //敦煌石窟体力CD恢复值
    public int DUNHUANGSHIKU_INIT_ENERGY = 30;                //敦煌石窟玩家体力值
    public int DUNHUANGSHIKU_ACTIVE_DAYS = 3;
    public int DUNHUANGSHIKU_ACTIVE_TITLE = 15;
    public int DUNHUANGSHIKU_THRESHOLD_SECURITY_NUM = 10;     //敦煌石窟触发玩家保底阈值
    public int DUNHUANGSHIKU_ATTACK_CD = 7200;                //敦煌石窟攻击冷却CD时间（s）
    public String DUNHUANGSHIKU_COLORING_PROP_ID = "121049|121050|121051|121052";     //敦煌石窟颜料ID列表(红黄蓝绿)
    public int DUNHUANGSHIKU_LEAVE_TEAM_CD = 7200;            //敦煌石窟主动离队，加入其他队的CD时间(s)
    public int DUNHUANGSHIKU_LOG_LIMIT = 50;                 //敦煌石窟日志显示上限
    public int DUNHUANGSHIKU_CHAT_LIMIT = 100;                //敦煌石窟聊天显示上限
    public int DUNHUANGSHIKU_GET_TEAM_LIST_PAGE_NUM = 50;      //敦煌石窟获取可申请的队伍每页队伍个数
    public int DUNHUANGSHIKU_APPLY_MAX_LIMIT = 100;      //敦煌石窟申请队伍上限
    public int DUNHUANGSHIKU_DAILY_OPEN_TIME = 10;      //敦煌石窟每日开启时间(h)

    public int DUNHUANGSHIKU_USER_APPLY_MAX_LIMIT = 3;      //敦煌石窟玩家队伍申请队伍上限
    public int DUNHUANGSHIKU_START_TEAM_ID = 0;      //敦煌石窟队伍起始id（不包括）
    public int DUNHUANGSHIKU_CAlC_HP_ADD_PAR = 1100;      //敦煌石窟怪物血量计算保底递增千分比
    public int DUNHUANGSHIKU_PROTECT_TIME = 60;      //敦煌石窟第三层保护时间
    public int DUNHUANGSHIKU_ENTER_MAX_REGION_REWARD = 2;      //敦煌石窟进入第三区域获得书的数量
    public int DUNHUANGSHIKU_LEAVE_MAX_REGION_PUNISH = 1;      //敦煌石窟第三区域掉落扣书的数量
    public int DUNHUANGSHIKU_CAN_CROSS_TEAM_UP = 0;      //敦煌石窟是否支持跨服组队（0不行，1可以）
    public String DUNHUANGSHIKU_FLOAT_VALUE = "95;105";      //敦煌石窟计算NPC血量浮动值区间(百分比)
    public int DUNHUANGSHIKU_DROP_BOOK_NUM_COEFFICIENT_1 = 20;      //敦煌石窟掉落文书计算系数1（百分比）
    public int DUNHUANGSHIKU_DROP_REWARD_QUALITY = 5;      //敦煌石窟NPC掉落奖励品质大于等于某个值 显示日志

    public int maxRegionId = 10003; // 最高的区域id

    public List<Integer> floatValueList = new ArrayList<>();// 敦煌石窟计算NPC血量浮动值区间(百分比)
    public List<Integer> coloringIdList = new ArrayList<>();// 敦煌石窟颜料ID列表(红黄蓝绿)
    public List<DunHuangShiKuRegionConfig> regionConfigList = new ArrayList<>(); // 区域配置
    public Map<Integer, DunHuangShiKuRegionConfig> regionConfigMap = new ConcurrentHashMap<>(); // 区域配置

    public List<DunHuangShiKuEventConfig> eventConfigList = new ArrayList<>();// 事件配置
    public Map<Integer, DunHuangShiKuEventConfig> eventConfigMap = new ConcurrentHashMap<>();// 事件配置

    public List<DunHuangShiKuMuralConfig> muralConfigList = new ArrayList<>(); // 壁画配置
    public Map<Integer, DunHuangShiKuMuralConfig> muralConfigMap = new ConcurrentHashMap<>(); // 壁画配置

    public int initHelpTimes = 200; //初始化协助次数
    public int helpConsumeHp = 20;
    public int helpAddTimes = 1;

    public DunHuangShiKuActivity(ActivityInfo activityInfo, int groupId) {
        initActivityConfigInfo(activityInfo.getActivityId());
        this.activityId = activityInfo.getActivityId();
        this.groupId = groupId;
        int teamId = UserDunHuangShiKuActivityBusiness.getMaxTeamId(activityInfo.getActivityId(), groupId);
        if (teamId == 0) {
            teamId = DUNHUANGSHIKU_START_TEAM_ID;
        }
        this.maxTeamId = new AtomicInteger(teamId);
        getCrossActivityDetail();
        initActivityInfo(activityInfo.getActivityId());
    }

    public synchronized CrossActivityDetail getCrossActivityDetail() {
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId, true);
        if (crossActivityDetail.getParam1() == 0) {
            crossActivityDetail.setParam1(DateHelper.getCurrentSecond());
        }
        return crossActivityDetail;
    }


    /**
     * @param userId
     * @param userBaseInfo
     * @param earnSpeed    门客总赚钱值
     * @return
     */
    public DunHuangShiKuUser getDunHuangShiKuUser(long userId, UserBaseInfo userBaseInfo, long earnSpeed, long attack, long blood) {
        DunHuangShiKuUser dunHuangShiKuUser = userMap.get(userId);
        if (null == dunHuangShiKuUser) {
            // 初始化玩家
            DunHuangShiKuUserData dunHuangShiKuUserData = new DunHuangShiKuUserData(activityId, groupId, userId);
            dunHuangShiKuUserData.setServerId(userBaseInfo.getServerId());
            if (regionConfigList != null) {
                dunHuangShiKuUserData.setRegionId(regionConfigList.get(0).getId());
                dunHuangShiKuUserData.setUnlockRegionId(regionConfigList.get(0).getId());
            }
            dunHuangShiKuUserData.setEnergy(DUNHUANGSHIKU_INIT_ENERGY);
            dunHuangShiKuUserData.setEnergyLastTime(System.currentTimeMillis() / 1000);
            dunHuangShiKuUser = new DunHuangShiKuUser(dunHuangShiKuUserData);
            userMap.put(userId, dunHuangShiKuUser);
        }
        // 每次获取都刷新攻击力 和 玩家信息
        dunHuangShiKuUser.baseInfo.setUserBaseInfo(userBaseInfo);
        dunHuangShiKuUser.baseInfo.setAttack(attack);
        if (dunHuangShiKuUser.baseInfo.getRegionId() != maxRegionId) {
            dunHuangShiKuUser.baseInfo.setBlood(blood);
        }
        dunHuangShiKuUser.baseInfo.setEarn(earnSpeed);

        dunHuangShiKuUser.baseInfo.setCurPatronsEarn(earnSpeed);
        return dunHuangShiKuUser;
    }

    /**
     * 添加队伍
     *
     * @param team
     */
    public void addDunHuangShiKuTeam(DunHuangShiKuTeam team) {
        teamMap.put(team.baseInfo.getTeamId(), team);
        teamList.add(team);
        List<DunHuangShiKuTeam> list = serverTeamsMap.get(team.baseInfo.getUserServerId());
        if (list == null) {
            list = new ArrayList<>();
            serverTeamsMap.put(team.baseInfo.getUserServerId(), list);
        }
        list.add(team);
    }

    /**
     * 创建队伍
     *
     * @param name
     * @param leader
     * @return
     */
    public DunHuangShiKuTeam createDunHuangShiKuTeam(String name, DunHuangShiKuUser leader) {
        long now = System.currentTimeMillis() / 1000;
        DunHuangShiKuTeamData baseInfo = new DunHuangShiKuTeamData(activityId, groupId, maxTeamId.incrementAndGet());
        baseInfo.setUserId(leader.baseInfo.getUserId());
        baseInfo.setUserServerId(leader.baseInfo.getServerId());
        baseInfo.setName(name);
        baseInfo.setCreateTime(now);
        // 初始化壁画
        DunHuangShiKuTeam team = new DunHuangShiKuTeam(baseInfo, leader);
        addDunHuangShiKuTeam(team);

        addTeamChat(team, leader, 3, eChatContentType.Common.getContentType(), name, now);

        leader.baseInfo.setTeamId(baseInfo.getTeamId());
        leader.baseInfo.setIsEnter(true);
        leader.baseInfo.setLastTimeCreateTime(now);
        addMember(team, leader);

        // 日志
        CrossAutoLogMgr.add(new LogDunHuangShiKuTeam(activityId, baseInfo.getTeamId(), leader.baseInfo.getUserId(), 0, ""));
        return team;
    }

    /**
     * 添加成员
     *
     * @param team
     * @param member
     */
    public void addMember(DunHuangShiKuTeam team, DunHuangShiKuUser member) {
        team.memberMap.put(member.baseInfo.getUserId(), member);
        member.baseInfo.setTeamId(team.baseInfo.getTeamId());
        if (member.inActivity) {
            member.baseInfo.setIsEnter(true);
        }
        if (team.baseInfo.getUserId() != member.baseInfo.getUserId()) {
            addTeamChat(team, member, 1, eChatContentType.Common.getContentType(), null, System.currentTimeMillis() / 1000);
        }
        // 日志
        CrossAutoLogMgr.add(new LogDunHuangShiKuTeamMember(activityId, member.baseInfo.getUserId(), team.baseInfo.getTeamId(), (team.baseInfo.getUserId() == member.baseInfo.getUserId() ? 1 : 0), 0, 0));
    }

    /**
     * 成员离开队伍
     *
     * @param team
     * @param member
     * @param type   退出队伍的方式 1被踢 2解散 3主动离队
     */
    public void memberQuitTeam(DunHuangShiKuTeam team, DunHuangShiKuUser member, int type) {
        team.memberMap.remove(member.baseInfo.getUserId());
        int identity = (team.baseInfo.getUserId() == member.baseInfo.getUserId() ? 1 : 0);
        long now = System.currentTimeMillis() / 1000;
        if ((type == 2 && team.baseInfo.getUserId() == member.baseInfo.getUserId()) || type == 3) {
            member.baseInfo.setLastTimeLeaveTime(now);
        }
        if (type != 2) {
            addTeamChat(team, member, 2, eChatContentType.Common.getContentType(), null, now);
        }
        if (type != 3 && member.baseInfo.getUserId() != team.baseInfo.getUserId()) {
            if (member.inActivity) {
                // 同步区服玩家数据
                DunHuangShiKuProto.DunHuangShiKuLeaveInfoEntity.Builder leaveInfo = DunHuangShiKuProto.DunHuangShiKuLeaveInfoEntity.newBuilder();
                leaveInfo.setType(1);
                leaveInfo.setLeaderServerId(team.baseInfo.getUserServerId());
                leaveInfo.setTeamName(team.baseInfo.getName());
                leaveInfo.setLeaderName(team.leaderInfo.baseInfo.getUserBaseInfo().getNickName());
                MessageHelper.sendPacket(member.baseInfo.getServerId(), member.baseInfo.getUserId(),
                        YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_LEAVE_INFO, leaveInfo));
            } else {
                member.baseInfo.setLeaveInfo(new DunHuangShiKuLeaveInfo(type, team.baseInfo.getUserId(), team.baseInfo.getName()));
            }
        }
        member.baseInfo.setTeamId(0);
        member.baseInfo.setIsEnter(false);
        // 日志
        CrossAutoLogMgr.add(new LogDunHuangShiKuTeamMember(activityId, member.baseInfo.getUserId(), team.baseInfo.getTeamId(), identity, 1, type));
    }

    /**
     * 新增聊天
     *
     * @param team    队伍
     * @param user    玩家
     * @param type    类型 0玩家发言 1加入 2离开 3创建队伍 4协助信息(recordId|eventId  (|targetServerId|targetName|decoration） 玩家事件才有 )
     * @param content
     * @param now     发送时间
     */
    public void addTeamChat(DunHuangShiKuTeam team, DunHuangShiKuUser user, int type, int contentType, String content, long now) {
        // 设置上限值
        if (team.chatList.getDataListCount() >= DUNHUANGSHIKU_CHAT_LIMIT && team.chatList.getDataListCount() != 0) {
            team.chatList.removeDataList(0);
        }
        WorldMessageProto.WorldMessageTempMsg.Builder messageTempMsg = WorldMessageProto.WorldMessageTempMsg.newBuilder();
        // type 0 普通聊天 1加入 2离开 3创建队伍 4协助信息
        messageTempMsg.setType(type);
        messageTempMsg.setContentType(contentType);
        messageTempMsg.setUserId(user.baseInfo.getUserId());
        if (content != null) {
            messageTempMsg.setContent(content);
        }
        messageTempMsg.setSendTime(now);
        PlayerProto.PlayerBaseTempMsg.Builder baseMsg = PlayerBasePb.parsePlayerBaseTempMsg(user.baseInfo.getUserBaseInfo());
        messageTempMsg.setPlayerBaseData(baseMsg);
        team.chatList.addDataList(messageTempMsg.build());
        DunHuangShiKuProto.DunHuangShiKuTeamChatEntity.Builder builder = DunHuangShiKuProto.DunHuangShiKuTeamChatEntity.newBuilder();
        builder.setMsg(messageTempMsg);
        for (DunHuangShiKuHelpRecordData item : getHelpRecordDataMap(team).values()) {
            // 当前正在求助的记录id
            builder.addRecordList(DunHuangShiKuProto.DunHuangShiKuHelpSimpleRecordEntity.newBuilder().setId(item.getId()).setRecordTime(item.getRecordTime()));
        }
        // 通知在线的队友
        for (DunHuangShiKuUser member : team.memberMap.values()) {
            if (member.inActivity) {
                MessageHelper.sendPacket(member.baseInfo.getServerId(), member.baseInfo.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_TEAM_CHAT, builder));
            }
        }
    }

    /**
     * 检查名字是否存在
     *
     * @param name
     * @return
     */
    public boolean checkTeamNameSame(String name) {
        for (DunHuangShiKuTeam item : teamList) {
            if (Objects.equals(item.baseInfo.getName(), name)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 联盟关闭所有的申请信息
     *
     * @param dunHuangShiKuTeam
     */
    public void cancelAllTeamApply(DunHuangShiKuTeam dunHuangShiKuTeam) {
        List<DunHuangShiKuUser> list = new ArrayList(dunHuangShiKuTeam.getApplyJoinUserMap().values());
        for (DunHuangShiKuUser item : list) {
            // 移除申请玩家的申请列表
            DunHuangShiKuUser applyUser = userMap.get(item.baseInfo.getUserId());
            if (applyUser != null) {
                cancelApply(applyUser, dunHuangShiKuTeam, false);
            }
        }
    }

    /**
     * 玩家取消 对所有联盟的申请
     */
    public void cancelApply(DunHuangShiKuUser dunHuangShiKuUser, boolean isBroadcast) {
        List<Integer> list = new ArrayList(dunHuangShiKuUser.baseInfo.getApplyJoinTeamMap().keySet());
        for (Integer item : list) {
            DunHuangShiKuTeam applyTeam = teamMap.get(item);
            if (null != applyTeam) {
                cancelApply(dunHuangShiKuUser, applyTeam, isBroadcast);
            }
        }
    }

    /**
     * 取消申请
     *
     * @param user
     * @param team
     * @param isBroadcast 是否广播给队长
     */
    public void cancelApply(DunHuangShiKuUser user, DunHuangShiKuTeam team, boolean isBroadcast) {
        // 移除联盟上面的申请
        team.getApplyJoinUserMap().remove(user.baseInfo.getUserId());
        // 移除玩家身上的记录
        if (user.baseInfo.getApplyJoinTeamMap().remove(team.baseInfo.getTeamId()) != null) {
            user.baseInfo.setUpdateOption();
        }
        if (isBroadcast) {
            // 通知队长
            DunHuangShiKuProto.DunHuangShiKuApplyChangeEntity.Builder changeBuilder = DunHuangShiKuMgr.builderDunHuangShiKuApplyChangeEntity(1, null, user.baseInfo.getUserId());
            MessageHelper.sendPacket(team.leaderInfo.baseInfo.getServerId(), team.leaderInfo.baseInfo.getUserId(),
                    YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_TEAM_APPLY, changeBuilder));
        }

    }

    /**
     * 尝试进入下一幅画
     *
     * @param team
     */
    public void nextMural(DunHuangShiKuTeam team, int curMuralId) {
        DunHuangShiKuMuralInfo muralInfo = team.baseInfo.getMuralInfoMap().get(curMuralId);
        if (muralInfo == null) {
            return;
        }
        DunHuangShiKuMuralConfig curConfig = muralConfigMap.get(curMuralId);
        for (int i = 0; i < curConfig.needColourList.size(); i++) {
            Integer coloringId = coloringIdList.get(i);
            if (curConfig.needColourList.get(i) > muralInfo.getColourMap().getOrDefault(coloringId, 0)) {
                // 未完成
                return;
            }
        }
        if (team.baseInfo.getCurFinishMuralId() < curMuralId) {
            muralInfo.getColourMap().clear();
            team.baseInfo.setUpdateOption();
            team.baseInfo.setCurFinishMuralId(curMuralId);
            // 通知队友 可以领取奖励
            for (DunHuangShiKuUser item : team.memberMap.values()) {
                MessageHelper.sendPacket(item.baseInfo.getServerId(), item.baseInfo.getUserId(), new YanQuMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_MURAL_REWARD));
            }
            CrossAutoLogMgr.add(new LogDunHuangShiKuFinishMural(activityId, team.baseInfo.getTeamId(), curMuralId));
        }
    }

    /**
     * 刷新玩家体力
     */
    public void refreshDunHuangShiKuUser(DunHuangShiKuUser user, boolean forceUpdate) {
        long now = System.currentTimeMillis() / 1000;
        long time = now - user.baseInfo.getEnergyLastTime();
        if (user.baseInfo.getEnergy() < DUNHUANGSHIKU_INIT_ENERGY) {
            int timesCD = (int) (time / DUNHUANGSHIKU_ENERGY_CD);
            if (timesCD > 0) {
                int times = timesCD * DUNHUANGSHIKU_ENERGY_CD_NUM;
                if (times + user.baseInfo.getEnergy() < DUNHUANGSHIKU_INIT_ENERGY) {
                    user.baseInfo.setEnergyLastTime(user.baseInfo.getEnergyLastTime() + timesCD * DUNHUANGSHIKU_ENERGY_CD);
                    user.baseInfo.setEnergy(user.baseInfo.getEnergy() + times);
                } else {
                    user.baseInfo.setEnergyLastTime(now);
                    user.baseInfo.setEnergy(DUNHUANGSHIKU_INIT_ENERGY);
                }
            }
        } else {
            if (forceUpdate) {
                user.baseInfo.setEnergyLastTime(now);
            }
        }

    }

    /**
     * 随机玩家事件
     *
     * @param huangShiKuRegionConfig
     * @param boxKeyNumMap
     * @return
     */
    public DunHuangShiKuEventConfig randomEventId(DunHuangShiKuUser dunHuangShiKuUser, DunHuangShiKuTeam team, DunHuangShiKuRegionConfig huangShiKuRegionConfig, Map<Integer, Integer> boxKeyNumMap) {
        long targetId = getTouchPlayerFightUserId(dunHuangShiKuUser, team);
        DunHuangShiKuEventConfig eventConfig = null;
        // 保底值判断
        if (dunHuangShiKuUser.securityTimes >= this.DUNHUANGSHIKU_THRESHOLD_SECURITY_NUM && huangShiKuRegionConfig.securityEventList.size() > 0) {
            // 触发保底
            List<Integer> canRandomList = new ArrayList<>(huangShiKuRegionConfig.securityEventList);
            if (targetId <= 0) {
                Iterator<Integer> iterator = canRandomList.iterator();
                while (iterator.hasNext()) {
                    Integer eventId = iterator.next();
                    DunHuangShiKuEventConfig config = eventConfigMap.get(eventId);
                    if (config.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
                        iterator.remove();
                    }
                }
            }
            if (canRandomList.size() > 0) {
                int index = random.next(canRandomList.size());
                Integer eventId = canRandomList.get(index);
                eventConfig = eventConfigMap.get(eventId);
                if (eventConfig.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
                    dunHuangShiKuUser.baseInfo.setTargetId(targetId);
                }
                dunHuangShiKuUser.baseInfo.setEventId(eventConfig.getId());
                dunHuangShiKuUser.securityTimes = 0;
                return eventConfig;
            }
        }
        HashMap<Integer, Integer> canRandomMap = new HashMap<>(huangShiKuRegionConfig.eventMap);
        if (targetId <= 0) {
            // 移除玩家事件
            Iterator<Integer> iterator = canRandomMap.keySet().iterator();
            while (iterator.hasNext()) {
                Integer eventId = iterator.next();
                DunHuangShiKuEventConfig config = eventConfigMap.get(eventId);
                if (config.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
                    iterator.remove();
                }
            }
        }

        Iterator<Integer> iterator = canRandomMap.keySet().iterator();
        while (iterator.hasNext()) {
            Integer eventId = iterator.next();
            DunHuangShiKuEventConfig config = eventConfigMap.get(eventId);
            if (config.getEventType() == eDunHuangShiKuEventType.Box.getValue()) {
                Integer keyNum = boxKeyNumMap.get(eventId);
                if (keyNum == null) {
                    keyNum = 0;
                }
                //有钥匙  且 钥匙大于指定数量
                if (config.getSecurityTimes() > 0 && dunHuangShiKuUser.baseInfo.getAllEventNumMap().getOrDefault(eventId, 0) >= keyNum + config.getSecurityTimes()) {
                    iterator.remove();
                }
            }
        }

        if (canRandomMap.size() > 0) {
            int sumWeight = 0;
            for (Integer weight : canRandomMap.values()) {
                sumWeight += weight;
            }
            int randomValue = random.next(0, sumWeight);
            int tempWeight = 0;
            for (Map.Entry<Integer, Integer> entry : canRandomMap.entrySet()) {
                tempWeight += entry.getValue();
                if (tempWeight > randomValue) {
                    eventConfig = eventConfigMap.get(entry.getKey());
                    break;
                }
            }
            if (eventConfig.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
                dunHuangShiKuUser.baseInfo.setTargetId(targetId);
            }
            dunHuangShiKuUser.baseInfo.setEventId(eventConfig.getId());
            if (!huangShiKuRegionConfig.securityEventList.contains(eventConfig.getId())) {
                dunHuangShiKuUser.securityTimes++;
            }
        }
        if (eventConfig == null) {
            DunHuangShiKuMgr.getLogger().error("没有可触发的事件！activityId:{},userId:{},region:{},当前区域3玩家数量:{}", activityId, dunHuangShiKuUser.baseInfo.getUserId(), huangShiKuRegionConfig.getId(), region3UserList.size());
        }
        return eventConfig;
    }


    /**
     * 获取触发玩家事件 目标玩家id
     * 1.未到最高层不能随机到玩家
     * 2.如果随机到玩家事件,不允许匹配到队友
     * 3.一个玩家只能被队伍里的一个人探索到和标记
     * 4.保护时间内不能被遇到
     * 5.保护时间内不能遇到玩家
     * 2021年7月13日14:19:01
     * 6.非本区服玩家＞同区服但非同商会玩家
     *
     * @param team
     * @return 如果返回0表示没有可遇到的玩家
     */
    private long getTouchPlayerFightUserId(DunHuangShiKuUser dunHuangShiKuUser, DunHuangShiKuTeam team) {
        // 未到最高层不能随机到玩家
        int now = DateHelper.getCurrentSecond();
        if (dunHuangShiKuUser.baseInfo.getRegionId() != maxRegionId || now < (dunHuangShiKuUser.enterMaxRegionTime + DUNHUANGSHIKU_PROTECT_TIME)) {
            return 0;
        }
        Set<Long> excludeTargetList = new HashSet<>();
//        for (DunHuangShiKuUser item : team.memberMap.values()) {
//            DunHuangShiKuEventConfig config = eventConfigMap.get(item.baseInfo.getEventId());
//            if (config != null && config.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
//                excludeTargetList.add(item.baseInfo.getTargetId());
//            }
//            if (item.currentHelpRecordData != null) {
//                DunHuangShiKuEventConfig recordConfig = eventConfigMap.get(item.currentHelpRecordData.getEventId());
//                if (recordConfig != null && recordConfig.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
//                    excludeTargetList.add(item.currentHelpRecordData.getTargetId());
//                }
//            }
//        }
        if (region3UserList.size() > 0) {
            // 非本区服玩家
            List<DunHuangShiKuUser> otherServerList = new ArrayList<>();
            // 同区服但非同商会玩家
            List<DunHuangShiKuUser> sameServerList = new ArrayList<>();

            for (DunHuangShiKuUser item : region3UserList) {
                if (now < (item.enterMaxRegionTime + DUNHUANGSHIKU_PROTECT_TIME) || team.memberMap.containsValue(item)
                        || excludeTargetList.contains(item.baseInfo.getUserId())) {
                    // 过滤保护中的玩家 队友 排除玩家
                    continue;
                }
                DunHuangShiKuUserData userBaseInfo = dunHuangShiKuUser.baseInfo;
                String userUnionUid = DunHuangShiKuMgr.getUserActivityUnionUid((int) userBaseInfo.getActivityId(), userBaseInfo.getUserId());
                DunHuangShiKuUserData itemBaseInfo = item.baseInfo;
                String itemUnionUid = DunHuangShiKuMgr.getUserActivityUnionUid((int) itemBaseInfo.getActivityId(), itemBaseInfo.getUserId());
                if (!StringUtils.isNullOrEmpty(userUnionUid) && itemUnionUid.equals(userUnionUid)) {
                    // 过滤同商会玩家
                    continue;
                }
                if (item.baseInfo.getServerId() != dunHuangShiKuUser.baseInfo.getServerId()) {
                    otherServerList.add(item);
                } else {
                    sameServerList.add(item);
                }
            }
            List<DunHuangShiKuUser> list = otherServerList.size() > 0 ? otherServerList : sameServerList;
            if (list.size() > 0) {
                int index = random.next(list.size());
                DunHuangShiKuUser targetUser = list.get(index);
                return targetUser.baseInfo.getUserId();
            }
        }
        return 0;
    }

    /**
     * 通知可以攻打该玩家 此时的剩余血量
     *
     * @param user
     * @param exclude 排除玩家
     */
    public void notifyRemainBlood(DunHuangShiKuUser user, DunHuangShiKuUser exclude, long damage) {
        // 看看要不要通知目标玩家  并且 如果目标死了怎么处理
        DunHuangShiKuProto.BroadcastDunHuangShiKuEventInfo.Builder builder = DunHuangShiKuProto.BroadcastDunHuangShiKuEventInfo.newBuilder();
        builder.setType(0);
        builder.setUserId(user.baseInfo.getUserId());
        builder.setRemainBlood(user.baseInfo.getRemainBlood());
        builder.setDamage(damage);
        Set<DunHuangShiKuUser> set = user.getCanAttackUserSet();

        // 广播给被攻击玩家的仇人们
        DunHuangShiKuMgr.broadcastMemberMsg(set, true, ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_EVENT_INFO, exclude.baseInfo.getUserId(), builder);
        if (user.inActivity && user.baseInfo.getRemainBlood() > 0) {
            // 广播给被攻击玩家剩余血量
            MessageHelper.sendPacket(user.baseInfo.getServerId(), user.baseInfo.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_EVENT_INFO, builder));
        }
    }

    /**
     * 玩家死亡处理
     *
     * @param deadUser
     * @param killUser   如果是队友帮忙击杀的，传的也是 所属记录的玩家
     * @param damage     最后一击 造成的伤害
     * @param isHelpKill 是否是被协助击杀
     * @param eventId
     * @param bookNum    攻击方获得文书数量
     */
    public void death(DunHuangShiKuUser deadUser, DunHuangShiKuUser killUser, DunHuangShiKuUser realKiller, long damage, boolean isHelpKill, int eventId, int bookNum, String reward) {
        // 修改击杀玩家的记录信息
        Set<DunHuangShiKuUser> set = deadUser.getCanAttackUserSet();
        for (DunHuangShiKuUser item : set) {
            // 探索到该死人的玩家
            if (item != killUser) {
                DunHuangShiKuEventConfig eventConfig = eventConfigMap.get(item.baseInfo.getEventId());
                if (eventConfig != null && eventConfig.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue() && item.baseInfo.getTargetId() == deadUser.baseInfo.getUserId()) {
                    // 移除 探索到该玩家的事件
                    removeEvent(item, false);
                    if (item.inActivity) {
                        DunHuangShiKuProto.BroadcastDunHuangShiKuEventInfo.Builder builder = DunHuangShiKuProto.BroadcastDunHuangShiKuEventInfo.newBuilder();
                        builder.setType(2);
                        MessageHelper.sendPacket(item.baseInfo.getServerId(), item.baseInfo.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_EVENT_INFO, builder));
                    }
                }
            }
            // 标记当前死人的玩家
            if (item.currentHelpRecordData != null && item.currentHelpRecordData.getTargetId() == deadUser.baseInfo.getUserId()) {
                // 修改 其他人的遇到该玩家的求助信息
                item.currentHelpRecordData.setKilledUserId(killUser.baseInfo.getUserId());
                item.currentHelpRecordData = null;
            }
        }
        set.clear();
        // 扣道具
        addBookNum(deadUser, -bookNum, 1, killUser.baseInfo.getUserId(), eventId);

        if (deadUser.inActivity) {
            // 广播给被攻击玩家
            DunHuangShiKuProto.BroadcastDunHuangShiKuDeathInfo.Builder builder = DunHuangShiKuProto.BroadcastDunHuangShiKuDeathInfo.newBuilder();
            builder.setAttackerName(killUser.baseInfo.getUserBaseInfo().getNickName());
            builder.setAttackerServerId(killUser.baseInfo.getServerId());
            builder.setDamage(damage);
            builder.setRobBookNum(bookNum);
            builder.setCurBookNum(deadUser.baseInfo.getBookNum());
            MessageHelper.sendPacket(deadUser.baseInfo.getServerId(), deadUser.baseInfo.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_DEATH_INFO, builder));
        } else {
            // 保留记录
            deadUser.baseInfo.setEnemyInfo(new DunHuangShiKuEnemyInfo(killUser.baseInfo.getUserId(), damage, bookNum));
        }
        // 重置区域
        dropRegion(deadUser, deadUser.baseInfo.getRegionId() - 1, false);
        // 敦煌击杀日志
        addKillUserLog(killUser, deadUser, realKiller, eventId, bookNum, reward);
        // 跑马灯
        broadcastDunHuangShiKuKillInfo(killUser, eventId, deadUser, bookNum);
        // 加击杀次数
        deadUser.baseInfo.getEnemyInfoMap().put(killUser.baseInfo.getUserId(), deadUser.baseInfo.getEnemyInfoMap().getOrDefault(killUser.baseInfo.getUserId(), 0) + 1);
        deadUser.baseInfo.setUpdateOption();
    }

    /**
     * 加珍贵文书
     *
     * @param user
     * @param num
     * @param type     改变途径(0进入第三层 1被击杀 2击杀玩家 3击杀npc 4记录领取)
     * @param targetId
     * @param eventId
     */
    public void addBookNum(DunHuangShiKuUser user, int num, int type, long targetId, int eventId) {
        if (num != 0) {
            int oldBookNum = user.baseInfo.getBookNum();
            user.baseInfo.setBookNum(user.baseInfo.getBookNum() + num);
            DunHuangShiKuTeam team = teamMap.get(user.baseInfo.getTeamId());
            team.bookNum = team.bookNum + num;
            updateTeamRank(team);
            // log
            CrossAutoLogMgr.add(new LogDunHuangShiKuBookNumChange(activityId, user.baseInfo.getUserId(), oldBookNum, user.baseInfo.getBookNum(), type, targetId, eventId));
        }
    }

    /**
     * 加被协助 / 攻击玩家流水
     *
     * @param type        日志类型 1对玩家攻击日志（不包含击杀） 2队友协助日志
     * @param targetUser  记录所属玩家
     * @param helpUser    攻击的玩家/ 协助的玩家
     * @param damage      0 表示击杀成功
     * @param eventConfig 事件配置
     * @param defender    type=2时，表示协助被攻击的玩家
     */
    public void addUserLog(byte type, DunHuangShiKuUser targetUser, DunHuangShiKuUser helpUser, long damage, DunHuangShiKuEventConfig eventConfig, DunHuangShiKuUser defender) {
        List<DunHuangShiKuKillLogData> list = targetUser.getUserLogDataList(true);
        synchronized (list) {
            while (list.size() >= DUNHUANGSHIKU_LOG_LIMIT && list.size() > 0) {
                list.remove(0);
            }
            DunHuangShiKuKillLogData userLogData = new DunHuangShiKuKillLogData();
            userLogData.setInsertOption();
            userLogData.setActivityId(this.activityId);
            userLogData.setType(type);
            userLogData.setUserId(targetUser.baseInfo.getUserId());

            userLogData.setAttackerId(helpUser.baseInfo.getUserId());
            if (type == 2) {
                if (defender != null) {
                    userLogData.setKillType((byte) 0);
                    userLogData.setTargetId(defender.baseInfo.getUserId());
                    userLogData.setTargetServerId(defender.baseInfo.getServerId());
                    userLogData.setTargetName(defender.baseInfo.getUserBaseInfo().getNickName());
                } else {
                    userLogData.setKillType((byte) 1);
                    userLogData.setTargetId(eventConfig.getTargetId());
                }
            }
            userLogData.setDamage(damage);
            userLogData.setEventId(eventConfig.getId());
            userLogData.setLogTime((int) (System.currentTimeMillis() / 1000));

            list.add(userLogData);
        }

    }

    /**
     * @param killUser   攻击方
     * @param deadUser   死者
     * @param realKiller 最后一击玩家
     * @param eventId
     * @param bookNum
     * @param reward
     */
    public void addKillUserLog(DunHuangShiKuUser killUser, DunHuangShiKuUser deadUser, DunHuangShiKuUser realKiller, int eventId, int bookNum, String reward) {
        addKillLog(killUser, deadUser, realKiller, (byte) 0, 0, eventId, bookNum, reward);
    }

    /**
     * @param killUser 攻击方
     */
    public void addKillNpcLog(DunHuangShiKuUser killUser, DunHuangShiKuUser realKiller, DunHuangShiKuEventConfig eventConfig, int bookNum, Property reward) {
        if (eventConfig.getIsShowLog() == 1) {
            for (Integer goodId : reward.getGoods().keySet()) {
                GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(goodId);
                if (goodsInfo != null && goodsInfo.getQuality() >= DUNHUANGSHIKU_DROP_REWARD_QUALITY) {
                    // 指定品质道具才显示日志
                    addKillLog(killUser, null, realKiller, (byte) 1, eventConfig.getTargetId(), eventConfig.getId(), bookNum, PropertyHelper.parsePropertyToString(reward));
                    break;
                }
            }
        }
    }

    /**
     * @param attacker
     * @param deadUser
     * @param realKiller 实际击杀的玩家或者说最后一击玩家
     * @param killType
     * @param npcId
     * @param eventId
     * @param bookNum    攻击方获得文书数量
     * @param reward
     */
    private void addKillLog(DunHuangShiKuUser attacker, DunHuangShiKuUser deadUser, DunHuangShiKuUser realKiller, byte killType, int npcId, int eventId, int bookNum, String reward) {
        while (killLogList.size() >= DUNHUANGSHIKU_LOG_LIMIT && killLogList.size() > 0) {
            killLogList.remove(0);
        }
        DunHuangShiKuKillLogData killLogData = new DunHuangShiKuKillLogData();
        killLogData.setInsertOption();
        killLogData.setActivityId(this.activityId);
        killLogData.setType((byte) 0);
        killLogData.setAttackerId(attacker.baseInfo.getUserId());
        killLogData.setKillType(killType);
        if (killLogData.getType() == 0 && realKiller != null) {
            killLogData.setRealKillId(realKiller.baseInfo.getUserId());
        }
        if (killType == 0) {
            if (deadUser != null) {
                // 玩家
                killLogData.setTargetId(deadUser.baseInfo.getUserId());
                killLogData.setTargetServerId(deadUser.baseInfo.getServerId());
                killLogData.setTargetName(deadUser.baseInfo.getUserBaseInfo().getNickName());
            }
        } else {
            // NPC
            killLogData.setTargetId(npcId);
        }
        killLogData.setEventId(eventId);
        killLogData.setBookNum(bookNum);
        killLogData.setLogTime((int) (System.currentTimeMillis() / 1000));
        killLogData.setReward(reward);
        killLogData.setKillNum(attacker.baseInfo.getCurKillNum());

        killLogList.add(killLogData);
        synchronized (killLogTempList) {
            killLogTempList.add(killLogData);
        }

    }

    /**
     * 跑马灯广播
     */
    public void broadcastDunHuangShiKuKillInfo(DunHuangShiKuUser attacker, int eventId, DunHuangShiKuUser deader, int bookNum) {
        DunHuangShiKuProto.BroadcastDunHuangShiKuKillInfo.Builder builder = DunHuangShiKuProto.BroadcastDunHuangShiKuKillInfo.newBuilder();
        builder.setAttackerServerId(attacker.baseInfo.getServerId());
        builder.setAttackerName(attacker.baseInfo.getUserBaseInfo().getNickName());
        builder.setEventId(eventId);
        if (deader != null) {
            builder.setDeaderServerId(deader.baseInfo.getServerId());
            builder.setDeaderName(deader.baseInfo.getUserBaseInfo().getNickName());
        }
        builder.setKillNum(attacker.baseInfo.getCurKillNum());
        builder.setBookNum(bookNum);
        DunHuangShiKuMgr.broadcastMemberMsg(userMap.values(), true, ClientProtocol.U_DUN_HUANG_SHI_KU_GET_KILL_INFO, 0, builder);
    }


    /**
     * 玩家被击杀  下降区域
     *
     * @param user
     */
    public void dropRegion(DunHuangShiKuUser user, int regionId, boolean isRemoveCurHelpRecord) {
        if (user.baseInfo.getRegionId() == maxRegionId) {
            region3UserList.remove(user);
        }
        if (isRemoveCurHelpRecord) {
            removeEvent(user, true);
        } else {
            boolean isRemove2 = true;
            if (user.currentHelpRecordData != null && user.currentHelpRecordData.getEventId() == user.baseInfo.getEventId() && user.currentHelpRecordData.getTargetId() == user.baseInfo.getTargetId()) {
                // 标记中还存在就不移除
                isRemove2 = false;
            }
            removeEvent(user, isRemove2);
        }
        clearUserData(user, isRemoveCurHelpRecord);
        user.baseInfo.setRegionId(regionId);
    }

    /**
     * 清空玩家数据
     *
     * @param user
     * @param isRemoveCurHelpRecord 是否移除当前标记
     */
    public void clearUserData(DunHuangShiKuUser user, boolean isRemoveCurHelpRecord) {
        user.baseInfo.setCurRobBookNum(0);
        user.baseInfo.setCurKillNum(0);
        // 移除标记的事件
        if (isRemoveCurHelpRecord && user.currentHelpRecordData != null) {
            user.currentHelpRecordData.setKilledUserId(-1);
            user.currentHelpRecordData = null;
        }
        user.baseInfo.setRemainBlood(0);
        // 清空仇人列表
        user.getCanAttackUserSet().clear();
    }


    /**
     * 移除玩家事件
     *
     * @param user
     * @param isRemove 如果是玩家事件 是否从目标玩家的仇人列表中移除
     */
    public void removeEvent(DunHuangShiKuUser user, boolean isRemove) {
        if (isRemove) {
            DunHuangShiKuEventConfig eventConfig = eventConfigMap.get(user.baseInfo.getEventId());
            if (eventConfig != null && eventConfig.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
                // 移除目标玩家的仇人列表
                DunHuangShiKuUser targetUser = userMap.get(user.baseInfo.getTargetId());
                if (targetUser != null) {
                    targetUser.getCanAttackUserSet().remove(user);
                }
            }
        }
        user.baseInfo.setEventId(0);
        user.baseInfo.setTargetId(0);
        user.baseInfo.setTargetTotalBlood(0);
        user.baseInfo.setAttackStatus(0);
        user.baseInfo.setLastAttackTime(0);
    }

    /**
     * 初始化活动DB数据
     *
     * @param activityId
     */
    public void initActivityInfo(int activityId) {
        // 队伍信息
        Map<Integer, DunHuangShiKuTeamData> teamDataMap = UserDunHuangShiKuActivityBusiness.getDunHuangShiKuTeamDataMap(activityId, groupId);
        for (DunHuangShiKuTeamData item : teamDataMap.values()) {
            if (!item.isDelete()) {
                addDunHuangShiKuTeam(new DunHuangShiKuTeam(item));
            }
        }
        this.npcBloodMap = UserDunHuangShiKuActivityBusiness.getDunHuangShiKuNpcBloodDataMap(activityId, groupId);
        // 玩家信息
        Map<Long, DunHuangShiKuUserData> userDataMap = UserDunHuangShiKuActivityBusiness.getDunHuangShiKuUserDataMap(activityId, groupId);
        for (DunHuangShiKuUserData item : userDataMap.values()) {
            DunHuangShiKuUser dunHuangShiKuUser = new DunHuangShiKuUser(item);
            userMap.put(item.getUserId(), dunHuangShiKuUser);
            if (item.getTeamId() != 0) {
                DunHuangShiKuTeam team = teamMap.get(item.getTeamId());
                if (team == null) {
                    DunHuangShiKuMgr.getLogger().error("敦煌石窟数据异常,userId:{}的玩家有teamId:{},但是没有对应的队伍对象。", item.getUserId(), item.getTeamId());
                    continue;
                }
                team.memberMap.put(item.getUserId(), dunHuangShiKuUser);
                if (team.baseInfo.getUserId() == item.getUserId()) {
                    // 队长
                    team.leaderInfo = dunHuangShiKuUser;
                }
                team.bookNum += item.getBookNum();
            }
            // 初始队伍申请列表
            for (Integer teamId : item.getApplyJoinTeamMap().keySet()) {
                DunHuangShiKuTeam team = teamMap.get(teamId);
                if (team == null) {
                    DunHuangShiKuMgr.getLogger().info("敦煌石窟数据异常,userId:{},activityId:{},teamId:{}。", item.getUserId(), item.getActivityId(), teamId);
                    continue;
                }
                team.getApplyJoinUserMap().put(item.getUserId(), dunHuangShiKuUser);
            }
            // 加载区域3玩家数据
            if (dunHuangShiKuUser.baseInfo.getRegionId() == maxRegionId) {
                region3UserList.add(dunHuangShiKuUser);
            }
        }
        teamList.forEach(e -> {
            if (e.bookNum > 0) {
                teamRankList.add(e);
            }
        });
        updateTeamRankList(true);

        for (DunHuangShiKuUser item : userMap.values()) {
            // 加入仇人列表
            DunHuangShiKuEventConfig eventConfig = eventConfigMap.get(item.baseInfo.getEventId());
            if (eventConfig != null) {
                if (eventConfig.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
                    DunHuangShiKuUser targetUser = userMap.get(item.baseInfo.getTargetId());
                    targetUser.getCanAttackUserSet().add(item);
                }
            }
        }
        // 求助信息
        List<DunHuangShiKuHelpRecordData> recordList =
                UserDunHuangShiKuActivityBusiness.getDunHuangShiKuHelpRecordData(activityId, groupId);
        for (DunHuangShiKuHelpRecordData item : recordList) {
            DunHuangShiKuUser dunHuangShiKuUser = userMap.get(item.getUserId());
            if (dunHuangShiKuUser == null) {
                DunHuangShiKuMgr.getLogger().error("敦煌石窟数据异常,userId:{}的玩家有协助对象但是没有对应的玩家。recordId:{}", item.getUserId(), item.getId());
                continue;
            }
            if (item.getKilledUserId() == 0) {
                if (dunHuangShiKuUser.currentHelpRecordData != null) {
                    DunHuangShiKuMgr.getLogger().info("敦煌石窟数据异常,userId:{}的玩家,存在多个当前标记的事件。recordId:{}与{}", item.getUserId(), item.getId(), dunHuangShiKuUser.currentHelpRecordData.getId());
                    continue;
                }
                dunHuangShiKuUser.currentHelpRecordData = item;
                // 加入仇人列表
                DunHuangShiKuEventConfig eventConfig = eventConfigMap.get(item.getEventId());
                if (eventConfig != null && eventConfig.getEventType() == eDunHuangShiKuEventType.PlayerFight.getValue()) {
                    DunHuangShiKuUser targetUser = userMap.get(item.getTargetId());
                    targetUser.getCanAttackUserSet().add(dunHuangShiKuUser);
                }
            }
            dunHuangShiKuUser.getHelpRecordDataMap(true).put(item.getId(), item);
        }

        // 日志 只加载今天日志
        int todayTime = (int) (DateHelper.getTodayZeroTimeStamp() / 1000);
        List<DunHuangShiKuKillLogData> killLogList =
                UserDunHuangShiKuActivityBusiness.getDunHuangShiKuKillLogData(activityId, todayTime);
        for (DunHuangShiKuKillLogData item : killLogList) {
            DunHuangShiKuUser dunHuangShiKuUser = userMap.get(item.getUserId());
            if (dunHuangShiKuUser == null) {
                //过滤非本分组的玩家
                DunHuangShiKuUser attackerUser = userMap.get(item.getAttackerId());
                if (attackerUser == null) {
                    continue;
                }
                // 公有
                if (this.killLogList.size() < DUNHUANGSHIKU_LOG_LIMIT) {
                    this.killLogList.add(item);
                }
            } else {
                // 玩家私有
                List<DunHuangShiKuKillLogData> list = dunHuangShiKuUser.getUserLogDataList(true);
                if (list.size() < DUNHUANGSHIKU_LOG_LIMIT) {
                    list.add(item);
                }
            }
        }
        this.killLogList.sort((DunHuangShiKuKillLogData t1, DunHuangShiKuKillLogData t2) -> {
            return Integer.compare(t1.getLogTime(), t2.getLogTime());
        });

        for (DunHuangShiKuUser item : userMap.values()) {
            List<DunHuangShiKuKillLogData> list = item.getUserLogDataList(false);
            if (list != null) {
                list.sort((DunHuangShiKuKillLogData t1, DunHuangShiKuKillLogData t2) -> {
                    return Integer.compare(t1.getLogTime(), t2.getLogTime());
                });
            }
        }
        refreshNpcBlood(false);
    }

    /**
     * 初始化活动配置数据
     */
    public void initActivityConfigInfo(int activityId) {
        DunHuangShiKuMgr.logger.info("加载敦煌配置 活动id：{}", activityId);
        // 其他配置
        List<Integer> activityIdList = new ArrayList<>();
        activityIdList.add(activityId);
        Map<String, ActivityConfig> activityConfigMap = ActivityBussiness.getActivityConfigMap(activityIdList).get(activityId);
        DUNHUANGSHIKU_ENERGY_CD = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_ENERGY_CD.getName()).getIntValue();
        DUNHUANGSHIKU_ENERGY_CD_NUM = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_ENERGY_CD_NUM.getName()).getIntValue();
        DUNHUANGSHIKU_INIT_ENERGY = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_INIT_ENERGY.getName()).getIntValue();
        DUNHUANGSHIKU_ACTIVE_DAYS = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_ACTIVE_DAYS.getName()).getIntValue();
        DUNHUANGSHIKU_ACTIVE_TITLE = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_ACTIVE_TITLE.getName()).getIntValue();
        DUNHUANGSHIKU_THRESHOLD_SECURITY_NUM = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_THRESHOLD_SECURITY_NUM.getName()).getIntValue();
        DUNHUANGSHIKU_ATTACK_CD = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_ATTACK_CD.getName()).getIntValue();
        DUNHUANGSHIKU_LOG_LIMIT = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_LOG_LIMIT.getName()).getIntValue();
        DUNHUANGSHIKU_CHAT_LIMIT = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_CHAT_LIMIT.getName()).getIntValue();
        DUNHUANGSHIKU_TEAM_NAME_LENGTH_LIMIT = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_TEAM_NAME_LENGTH_LIMIT.getName()).getIntValue();
        DUNHUANGSHIKU_LEAVE_TEAM_CD = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_LEAVE_TEAM_CD.getName()).getIntValue();
        DUNHUANGSHIKU_GET_TEAM_LIST_PAGE_NUM = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_GET_TEAM_LIST_PAGE_NUM.getName()).getIntValue();
        DUNHUANGSHIKU_SCORE_ITEM_ID = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_SCORE_ITEM_ID.getName()).getIntValue();
        DUNHUANGSHIKU_ENERGY_ITEM_ID = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_ENERGY_ITEM_ID.getName()).getIntValue();
        DUNHUANGSHIKU_CREATE_TEAM_TIME = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_CREATE_TEAM_TIME.getName()).getIntValue();
        DUNHUANGSHIKU_CREATE_TEAM_NEED_INGOTS = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_CREATE_TEAM_NEED_INGOTS.getName()).getIntValue();
        DUNHUANGSHIKU_APPLY_MAX_LIMIT = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_APPLY_MAX_LIMIT.getName()).getIntValue();
        DUNHUANGSHIKU_DAILY_OPEN_TIME = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_DAILY_OPEN_TIME.getName()).getIntValue();

        DUNHUANGSHIKU_USER_APPLY_MAX_LIMIT = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_USER_APPLY_MAX_LIMIT.getName()).getIntValue();
        DUNHUANGSHIKU_START_TEAM_ID = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_START_TEAM_ID.getName()).getIntValue();
        DUNHUANGSHIKU_CAlC_HP_ADD_PAR = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_CAlC_HP_ADD_PAR.getName()).getIntValue();
        DUNHUANGSHIKU_PROTECT_TIME = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_PROTECT_TIME.getName()).getIntValue();
        DUNHUANGSHIKU_ENTER_MAX_REGION_REWARD = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_ENTER_MAX_REGION_REWARD.getName()).getIntValue();
        DUNHUANGSHIKU_LEAVE_MAX_REGION_PUNISH = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_LEAVE_MAX_REGION_PUNISH.getName()).getIntValue();
        DUNHUANGSHIKU_CAN_CROSS_TEAM_UP = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_CAN_CROSS_TEAM_UP.getName()).getIntValue();
        DUNHUANGSHIKU_COLORING_PROP_ID = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_COLORING_PROP_ID.getName()).getValue();
        DUNHUANGSHIKU_FLOAT_VALUE = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_FLOAT_VALUE.getName()).getValue();
        DUNHUANGSHIKU_DROP_BOOK_NUM_COEFFICIENT_1 = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_DROP_BOOK_NUM_COEFFICIENT_1.getName()).getIntValue();
        DUNHUANGSHIKU_DROP_REWARD_QUALITY = activityConfigMap.get(eActivityConfigType.DUNHUANGSHIKU_DROP_REWARD_QUALITY.getName()).getIntValue();
        coloringIdList = StringUtils.stringToIntegerList(DUNHUANGSHIKU_COLORING_PROP_ID, "\\|");
        floatValueList = StringUtils.stringToIntegerList(DUNHUANGSHIKU_FLOAT_VALUE, ";");
        if (activityConfigMap.containsKey("DUNHUANGSHIKU_INIT_HELP_TIMES")) {
            initHelpTimes = activityConfigMap.get("DUNHUANGSHIKU_INIT_HELP_TIMES").getIntValue();

        }
        if (activityConfigMap.containsKey("DUNHUANGSHIKU_CONSUME_ENERGY_HELP_TIMES")) {
            String helpTimesStr = activityConfigMap.get("DUNHUANGSHIKU_CONSUME_ENERGY_HELP_TIMES").getValue();
            String[] arr = helpTimesStr.split(",");
            helpConsumeHp = Integer.parseInt(arr[0]);
            helpAddTimes = Integer.parseInt(arr[1]);
        }
        muralConfigList = DunHuangShiKuActivityBusiness.getDunHuangShiKuMuralConfigList(activityId);
        for (DunHuangShiKuMuralConfig item : muralConfigList) {
            muralConfigMap.put(item.getId(), item);
        }
        regionConfigList = DunHuangShiKuActivityBusiness.getDunHuangShiKuRegionConfigList(activityId);
        for (DunHuangShiKuRegionConfig item : regionConfigList) {
            regionConfigMap.put(item.getId(), item);
            maxRegionId = item.getId();
        }
        eventConfigList = DunHuangShiKuActivityBusiness.getDunHuangShiKuEventConfigList(activityId);
        for (DunHuangShiKuEventConfig item : eventConfigList) {
            eventConfigMap.put(item.getId(), item);
        }

        for (DunHuangShiKuRegionConfig item : regionConfigList) {
            for (Integer eventId : item.eventMap.keySet()) {
                DunHuangShiKuEventConfig eventConfig = eventConfigMap.get(eventId);
                if (eventConfig == null) {
                    DunHuangShiKuMgr.getLogger().info("敦煌石窟配置异常，事件权重里的事件未找到配置。activityId:{},eventWeight:{},eventId:{}", activityId, item.getEventWeight(), eventId);
                    continue;
                }
                if (eventConfig.getSecurityTimes() == 1) {
                    item.securityEventList.add(eventId);
                }
            }
        }
    }

    /**
     * 攻击协助记录
     *
     * @param attacker   攻击者
     * @param helpedUser 被协助的玩家
     * @param helpRecord 协助记录
     * @param now        当前时间
     * @return list [0]是否击杀 [1]伤害 [2] 剩余血量 [3]获得积分
     */
    public List<Object> attackHelpRecord(DunHuangShiKuTeam team, DunHuangShiKuUser attacker, DunHuangShiKuUser helpedUser, DunHuangShiKuHelpRecordData helpRecord, long now) {
        DunHuangShiKuEventConfig huangShiKuEventConfig = eventConfigMap.get(helpRecord.getEventId());
        long damage = 0;
        boolean isKill = false;
        // 是否是自己的协助记录
        boolean isOwn = (attacker == helpedUser);
        // 是否也处于被协助玩家探索中
        boolean inExplore = (helpedUser.baseInfo.getAttackStatus() == 2);
        List<Object> list = null;
        if (huangShiKuEventConfig.getEventType() == eDunHuangShiKuEventType.NpcFight.getValue()) {
            // NPC事件
            // 剩余血量
            list = attackResult(helpRecord.getTargetId(), attacker.baseInfo.getAttack(), huangShiKuEventConfig.getScore(), helpRecord.getTargetTotalBlood());
            isKill = (boolean) list.get(0);
            damage = (long) list.get(1);
            long remainBlood = (long) list.get(2);
            helpRecord.setTargetId(remainBlood);
            if (helpedUser.baseInfo.getAttackStatus() == 2) {
                // 当前协助信息是否在玩家的探索事件中
                helpedUser.baseInfo.setTargetId(remainBlood);
            }
            // 协助流水
            if (!isOwn) {
                long killDamage = isKill ? 0 : damage;
                addUserLog((byte) 2, helpedUser, attacker, killDamage, huangShiKuEventConfig, null);
                if (helpedUser.inActivity) {
                    DunHuangShiKuProto.BroadcastDunHuangShiKuEventInfo.Builder builder = DunHuangShiKuProto.BroadcastDunHuangShiKuEventInfo.newBuilder();
                    builder.setType(1);
                    builder.setDamage(damage);
                    builder.setRemainBlood(remainBlood);
                    MessageHelper.sendPacket(helpedUser.baseInfo.getServerId(), helpedUser.baseInfo.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_EVENT_INFO, builder));
                }
            }
            if (isKill) {
                int bookNum = DunHuangShiKuMgr.calKillNpcDropBookNum(huangShiKuEventConfig);
                Property reward = DunHuangShiKuMgr.getDunHuangShiKuEventConfigReward(huangShiKuEventConfig);
                String rewardStr = PropertyHelper.parsePropertyToString(reward);
                helpRecord.setBookNum(bookNum);
                helpRecord.setReward(rewardStr);
                addKillNpcLog(helpedUser, attacker, huangShiKuEventConfig, bookNum, reward);
            }
        } else {
            // 玩家事件
            // 目标玩家
            DunHuangShiKuUser targetUser = userMap.get(helpRecord.getTargetId());
            list = attackResult(targetUser.baseInfo.getRemainBlood(), attacker.baseInfo.getAttack(), huangShiKuEventConfig.getScore(), helpRecord.getTargetTotalBlood());
            isKill = (boolean) list.get(0);
            damage = (long) list.get(1);
            long remainBlood = (long) list.get(2);
            targetUser.baseInfo.setRemainBlood(remainBlood);
            notifyRemainBlood(targetUser, attacker, damage);
            if (!isOwn) {
                long killDamage = isKill ? 0 : damage;
                addUserLog((byte) 2, helpedUser, attacker, killDamage, huangShiKuEventConfig, targetUser);
            }
            if (isKill) {
                int bookNum = DunHuangShiKuMgr.calKillUserDropBookNum(this, targetUser);

                helpedUser.baseInfo.setCurKillNum(helpedUser.baseInfo.getCurKillNum() + 1);
                helpedUser.baseInfo.setCurRobBookNum(helpedUser.baseInfo.getCurRobBookNum() + bookNum);

                Property reward = DunHuangShiKuMgr.getDunHuangShiKuEventConfigReward(huangShiKuEventConfig);
                String rewardStr = PropertyHelper.parsePropertyToString(reward);
                helpRecord.setBookNum(bookNum);
                helpRecord.setReward(rewardStr);
                death(targetUser, helpedUser, attacker, damage, !isOwn, huangShiKuEventConfig.getId(), bookNum, rewardStr);

            }
        }
        if (isOwn && inExplore) {
            // 如果是自己的 并且是探索中的
            attacker.baseInfo.setLastAttackTime(now);
        }
        if (isKill) {
            // 尝试移除 标记
            attemptRemoveCurHelpRecord(helpedUser, helpRecord.getTargetId(), false);
        }
        DunHuangShiKuAttackInfo attackInfo = helpRecord.getHelpAttackMap().get(attacker.baseInfo.getUserId());
        if (attackInfo == null) {
            attackInfo = new DunHuangShiKuAttackInfo();
            helpRecord.getHelpAttackMap().put(attacker.baseInfo.getUserId(), attackInfo);
        }
        if (!isOwn) {
            attackInfo.setDamage(attackInfo.getDamage() + damage);
        }
        attackInfo.setAttackTime(now);
        helpRecord.setUpdateOption();
        if (isKill) {
            broadcastHelpRecordAttackInfo(team.memberMap.values(), team);
        } else {
            List userList = new ArrayList();
            userList.add(attacker);
            broadcastHelpRecordAttackInfo(userList, team);
        }
        return list;
    }

    /**
     * 攻击结果
     *
     * @param curRemainBlood 当前剩余血量
     * @param attack         攻击力
     * @param score          积分
     * @param totalBlood     总血量
     * @return list [0]是否击杀 [1]伤害 [2] 剩余血量 [3]获得积分
     */
    public List<Object> attackResult(long curRemainBlood, long attack, long score, long totalBlood) {
        long remainBlood = Math.max(0, curRemainBlood - attack);
        boolean isKill = (remainBlood <= 0);
        long damage = isKill ? curRemainBlood : attack;
        long addScore = Math.max(1, (damage * score) / totalBlood);
        List<Object> list = new ArrayList<>();
        list.add(isKill);
        list.add(damage);
        list.add(remainBlood);
        list.add(addScore);
        return list;
    }

    /**
     * 更新队伍排名
     *
     * @param team
     */
    private void updateTeamRank(DunHuangShiKuTeam team) {
        team.baseInfo.setUpdateScoreTime(System.currentTimeMillis() / 1000);
        updateNum++;
        if (team.bookNum <= 0) {
            teamRankList.remove(team);
            team.rank = -1;
        } else {
            if (!teamRankList.contains(team)) {
                teamRankList.add(team);
            }
        }
        if (updateNum >= 1000) {
            updateTeamRankList(true);
        }
    }

    /**
     * 更新排行榜
     *
     * @param forceUpdate 是否强制更新
     */
    public void updateTeamRankList(boolean forceUpdate) {
        if (forceUpdate || updateNum > 0) {
            teamRankList.sort((t1, t2) -> {
                if (t1.bookNum != t2.bookNum) {
                    return Integer.compare(t2.bookNum, t1.bookNum);
                } else if (t1.baseInfo.getUpdateScoreTime() != t2.baseInfo.getUpdateScoreTime()) {
                    return Long.compare(t1.baseInfo.getUpdateScoreTime(), t2.baseInfo.getUpdateScoreTime());
                } else {
                    return Integer.compare(t1.baseInfo.getTeamId(), t2.baseInfo.getTeamId());
                }
            });
            int rank = 1;
            for (DunHuangShiKuTeam item : teamRankList) {
                if (item.bookNum > 0) {
                    item.rank = rank++;
                } else {
                    // 正常不会进来
                    item.rank = -1;
                }
            }
            updateNum = 0;
        }
    }

    public void save() {
        // 队伍
        for (DunHuangShiKuTeam dunHuangShiKuTeam : teamMap.values()) {
            if (dunHuangShiKuTeam.baseInfo.isUpdateOption()) {
                UserDunHuangShiKuActivityBusiness.updateDunHuangShiKuTeamData(dunHuangShiKuTeam.baseInfo);
            } else if (dunHuangShiKuTeam.baseInfo.isInsertOption()) {
                UserDunHuangShiKuActivityBusiness.addDunHuangShiKuTeamData(dunHuangShiKuTeam.baseInfo);
            }
        }
        for (DunHuangShiKuNpcBloodData item : this.npcBloodMap.values()){
            if (item.isInsertOption()) {
                UserDunHuangShiKuActivityBusiness.addDunHuangShiKuNpcBloodData(item);
            }
        }

        // 删除的队伍
        ArrayList<DunHuangShiKuTeam> tempList = null;
        synchronized (deleteList) {
            tempList = new ArrayList<>(deleteList);
            deleteList.clear();
        }
        for (DunHuangShiKuTeam dunHuangShiKuTeam : tempList) {
            if (dunHuangShiKuTeam.baseInfo.isUpdateOption()) {
                UserDunHuangShiKuActivityBusiness.updateDunHuangShiKuTeamData(dunHuangShiKuTeam.baseInfo);
            }
        }
        // 玩家
        for (DunHuangShiKuUser dunHuangShiKuUser : userMap.values()) {
            if (dunHuangShiKuUser.baseInfo.isUpdateOption()) {
                UserDunHuangShiKuActivityBusiness.updateDunHuangShiKuUserData(dunHuangShiKuUser.baseInfo);
            } else if (dunHuangShiKuUser.baseInfo.isInsertOption()) {
                UserDunHuangShiKuActivityBusiness.addDunHuangShiKuUserData(dunHuangShiKuUser.baseInfo);
            }
            // 协助记录
            Map<Long, DunHuangShiKuHelpRecordData> recordMap = dunHuangShiKuUser.getHelpRecordDataMap(false);
            if (recordMap != null) {
                List<DunHuangShiKuHelpRecordData> tempRecordList = new ArrayList<>(recordMap.values());
                for (DunHuangShiKuHelpRecordData item : tempRecordList) {
                    if (item.isUpdateOption()) {
                        UserDunHuangShiKuActivityBusiness.updateDunHuangShiKuHelpRecordData(item);
                    } else if (item.isInsertOption()) {
                        UserDunHuangShiKuActivityBusiness.addDunHuangShiKuHelpRecordData(item);
                    }
                }
            }
            // 玩家日志
            List<DunHuangShiKuKillLogData> logList = dunHuangShiKuUser.getUserLogDataList(false);
            if (logList != null) {
                ArrayList<DunHuangShiKuKillLogData> logTempList = null;
                synchronized (logList) {
                    logTempList = new ArrayList<>(logList);
                }
                for (DunHuangShiKuKillLogData item : logTempList) {
                    if (item.isInsertOption()) {
                        UserDunHuangShiKuActivityBusiness.addDunHuangShiKuKillLogData(item);
                    }
                }
            }
        }
        // 击杀
        ArrayList<DunHuangShiKuKillLogData> addKillLogTempList = null;
        synchronized (killLogTempList) {
            addKillLogTempList = new ArrayList<>(killLogTempList);
            killLogTempList.clear();
        }
        for (DunHuangShiKuKillLogData item : addKillLogTempList) {
            if (item.isInsertOption()) {
                UserDunHuangShiKuActivityBusiness.addDunHuangShiKuKillLogData(item);
            }
        }
    }

    /**
     * 实时获取队伍总赚钱值
     *
     * @param team
     */
    public long getTeamEarn(DunHuangShiKuTeam team) {
        long sumEarn = 0;
        for (DunHuangShiKuUser item : team.memberMap.values()) {
            sumEarn += item.baseInfo.getEarn();
        }
        return sumEarn;
    }

    /**
     * 获取队伍成员的求助信息
     *
     * @param team
     * @return k:协助id
     */
    public Map<Long, DunHuangShiKuHelpRecordData> getHelpRecordDataMap(DunHuangShiKuTeam team) {
        Map<Long, DunHuangShiKuHelpRecordData> helpRecordDataMap = new HashMap<>();
        for (DunHuangShiKuUser item : team.memberMap.values()) {
            if (item.currentHelpRecordData != null) {
                // 特殊代码 2022年4月12日14:26:48 修复数据用
                // 判断如果是自己玩家 并且是npc事件 血量小于0 没有击杀玩家 就设值
                DunHuangShiKuEventConfig huangShiKuEventConfig = eventConfigMap.get(item.currentHelpRecordData.getEventId());
                if (huangShiKuEventConfig != null && huangShiKuEventConfig.getEventType() == eDunHuangShiKuEventType.NpcFight.getValue() && item.currentHelpRecordData.getTargetId() <= 0 && item.currentHelpRecordData.getKilledUserId() <= 0) {
                    item.currentHelpRecordData.setKilledUserId(item.currentHelpRecordData.getUserId());
                    item.currentHelpRecordData = null;
                    continue;
                }
                helpRecordDataMap.put(item.currentHelpRecordData.getId(), item.currentHelpRecordData);
            }
        }
        return helpRecordDataMap;
    }

    /**
     * 获取队伍当前修复的壁画id
     *
     * @param team
     * @return
     */
    public int getCurMuralId(DunHuangShiKuTeam team) {
        if (regionConfigMap.size() <= 0) {
            return 0;
        }
        DunHuangShiKuMuralConfig finishConfig = muralConfigMap.get(team.baseInfo.getCurFinishMuralId());
        if (finishConfig == null) {
            return muralConfigList.get(0).getId();
        }
        int curConfigIndex = muralConfigList.indexOf(finishConfig) + 1;
        if (muralConfigList.size() - 1 >= curConfigIndex) {
            DunHuangShiKuMuralConfig curConfig = muralConfigList.get(curConfigIndex);
            return curConfig.getId();
        } else {
            return finishConfig.getId();
        }
    }

    /**
     * 最后一幅画id
     *
     * @return
     */
    public int getMaxMuralId() {
        if (muralConfigList.size() > 0) {
            return muralConfigList.get(muralConfigList.size() - 1).getId();
        } else {
            return 0;
        }
    }

    /**
     * 获取id血量
     *
     * @param npcId
     * @return
     */
    public long getNpcBlood(int npcId) {
        DunHuangShiKuNpcBloodData blood = npcBloodMap.get(npcId);
        if(blood == null){
            DunHuangShiKuMgr.logger.error("获取不到npc 血量");
            throw new RuntimeException("获取不到npc 血量");
        }
        long minBlood = (blood.getBlood() * floatValueList.get(0) + 100 - 1) / 100;
        long maxBlood = (blood.getBlood() * floatValueList.get(1) + 100 - 1) / 100;
        long diffBlood = 0;
        if (maxBlood > minBlood) {
            diffBlood = maxBlood - minBlood;
            diffBlood = RandomHelper.nextLong(diffBlood);
        }
        return minBlood + diffBlood;
    }

    /**
     * 是否强制刷新
     *
     * @param forceUpdate
     */
    public synchronized void refreshNpcBlood(boolean forceUpdate) {
        // 组队期开始后才能开始计算
        int now = DateHelper.getCurrentSecond();
        if (npcBloodMap.size() != 0 && !forceUpdate) {
            return;
        }
        List<DunHuangShiKuEventConfig> typeList1 = new ArrayList<>();
        for (DunHuangShiKuEventConfig item : eventConfigList) {
            if (item.getEventType() == eDunHuangShiKuEventType.NpcFight.getValue()) {
                typeList1.add(item);
            }
        }
        if (typeList1.size() <= 0) {
            return;
        }
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        if (activityInfo == null) {
            DunHuangShiKuMgr.getLogger().error("获取需要获取活跃玩家的区服集合 没有活动配置 activityId:{}", activityId);
            return;
        }
        long synTime = activityInfo.getBeginTime() + DUNHUANGSHIKU_DAILY_OPEN_TIME * DateHelper.HOUR_SECONDS;
        if (now < synTime || now >= activityInfo.getEndTime()) {
            return;
        }
        List<Long> serverList = getNeedSynActiveUserInfo();
        if (serverList.size() > 0) {
            DunHuangShiKuMgr.getLogger().error("活跃玩家数据尚未收集完成。activityId:{}, groupId:{}, serverList：{}", activityId, groupId, JSON.toJSONString(serverList));
            return;
        }
        // 1.获取参赛玩家排名
        List<DunHuangShiKuUserBloodInfo> userList = new ArrayList<>();
        for (List<DunHuangShiKuUserBloodInfo> list : allUserBloodMap.values()) {
            userList.addAll(list);
        }
        userList.sort((t1, t2) -> {
            return -Long.compare(t1.getEarn(), t2.getEarn());
        });

        if (DunHuangShiKuMgr.logger.isDebugEnabled()) {
            for (int i = 0; i < userList.size(); i++) {
                DunHuangShiKuUserBloodInfo item = userList.get(i);
                DunHuangShiKuMgr.getLogger().info("活跃玩家数据 userId:{},serverId:{} ,rank:{},earn:{}", item.getUserId(), item.getServerId(), i + 1, item.getEarn());
            }
        }

        // 2 计算每个npc血量
        long upEventBlood = 0;
        Map<Integer, DunHuangShiKuNpcBloodData> tempNpcBloodMap = new HashMap<>();
        for (int i = 0; i < typeList1.size(); i++) {
            LogDunHuangShiKuNpcBlood logDunHuangShiKuNpcBlood = new LogDunHuangShiKuNpcBlood();

            DunHuangShiKuEventConfig eventConfig = typeList1.get(i);
            String[] coefficientArray = eventConfig.getParam().split("\\|");
            // 基数1 血量基数1=对应名次区间内所有玩家的门客赚钱总值的平均值
            String[] rankArray = coefficientArray[0].split(";");
            int rank1 = Integer.valueOf(rankArray[0]);
            int rank2 = Integer.valueOf(rankArray[1]);
            DunHuangShiKuCalBloodBaseInfo baseValue1 = getAverageEarn(userList, rank1, rank2);

            // 基数2 血量基数2=百分比取值对应的玩家门客赚钱总值
            rankArray = coefficientArray[1].split(";");
            rank1 = (userList.size() * Integer.valueOf(rankArray[0]) + 1000 - 1) / 1000;
            rank2 = (userList.size() * Integer.valueOf(rankArray[1]) + 1000 - 1) / 1000;
            DunHuangShiKuCalBloodBaseInfo baseValue2 = getAverageEarn(userList, rank1, rank2);
            // 基数3 血量基数3=保底值
            long baseValue3 = Long.valueOf(coefficientArray[2]);
            // 基数4
            long baseValue4 = (upEventBlood * DUNHUANGSHIKU_CAlC_HP_ADD_PAR + 1000 - 1) / 1000;

            long blood = baseValue1.earn > baseValue2.earn ? baseValue1.earn : baseValue2.earn;
            blood = blood > baseValue3 ? blood : baseValue3;
            blood = blood > baseValue4 ? blood : baseValue4;

            upEventBlood = blood;
            DunHuangShiKuNpcBloodData bloodData = new DunHuangShiKuNpcBloodData(activityId, groupId, eventConfig.getId());
            bloodData.setEventId(eventConfig.getId());
            bloodData.setBlood(blood);
            bloodData.setCreateTime(now);
            bloodData.setInsertOption();
            tempNpcBloodMap.put(eventConfig.getId(), bloodData);

            logDunHuangShiKuNpcBlood.setActivityId(activityId);
            logDunHuangShiKuNpcBlood.setUserNum(userList.size());
            logDunHuangShiKuNpcBlood.setEventId(eventConfig.getId());
            logDunHuangShiKuNpcBlood.setBaseValue1(baseValue1.earn);
            logDunHuangShiKuNpcBlood.setStartRank1(baseValue1.startRank);
            logDunHuangShiKuNpcBlood.setEndRank1(baseValue1.endRank);
            logDunHuangShiKuNpcBlood.setNum1(baseValue1.num);
            logDunHuangShiKuNpcBlood.setEarnSum1(baseValue1.earnSum);
            logDunHuangShiKuNpcBlood.setBaseValue2(baseValue2.earn);
            logDunHuangShiKuNpcBlood.setStartRank2(baseValue2.startRank);
            logDunHuangShiKuNpcBlood.setEndRank2(baseValue2.endRank);
            logDunHuangShiKuNpcBlood.setNum2(baseValue2.num);
            logDunHuangShiKuNpcBlood.setEarnSum2(baseValue2.earnSum);
            logDunHuangShiKuNpcBlood.setBaseValue3(baseValue3);
            logDunHuangShiKuNpcBlood.setBaseValue4(baseValue4);
            logDunHuangShiKuNpcBlood.setBloodValue(blood);
            CrossAutoLogMgr.add(logDunHuangShiKuNpcBlood);
            DunHuangShiKuMgr.getLogger().info("活动id：{},事件id:{},基数1:{},基数2:{},基数3:{},基数4:{},最终血量取值为:{}", activityId, eventConfig.getId(), baseValue1.earn, baseValue2.earn, baseValue3, baseValue4, blood);
        }
        npcBloodMap = tempNpcBloodMap;
    }

    /**
     * 获取 队列中 [rank1,rank2] 的平均赚钱值
     *
     * @param userList
     * @param rank1
     * @param rank2
     * @return
     */
    private DunHuangShiKuCalBloodBaseInfo getAverageEarn(List<DunHuangShiKuUserBloodInfo> userList, int rank1, int rank2) {
        DunHuangShiKuCalBloodBaseInfo bloodBaseInfo = new DunHuangShiKuCalBloodBaseInfo();
        int num = 0;
        long earnSum = 0;
        for (int j = rank1; j <= rank2; j++) {
            if (j > userList.size()) {
                break;
            }
            int index = j - 1;
            if (index < 0) {
                // 防止配0的情况
                continue;
            }
            DunHuangShiKuUserBloodInfo item = userList.get(index);
            earnSum += item.getEarn();
            num++;
        }
        long earn = 0;
        if (num > 0) {
            earn = (earnSum + num - 1) / num;
        }
        bloodBaseInfo.startRank = rank1;
        bloodBaseInfo.endRank = rank2;
        bloodBaseInfo.num = num;
        bloodBaseInfo.earnSum = earnSum;
        bloodBaseInfo.earn = earn;

        DunHuangShiKuMgr.getLogger().info("userList.size:{},起始排名:{},结束排名{},含有个数:{},总赚钱值:{},平均值{}", userList.size(), rank1, rank2, num, earnSum, earn);
        return bloodBaseInfo;
    }

    /**
     * 是否处在组队期
     *
     * @return
     */
    private boolean isCreateTeamPeriod() {
        int now = DateHelper.getCurrentSecond();
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        long createTeamEndTime = activityInfo.getBeginTime() + DUNHUANGSHIKU_CREATE_TEAM_TIME * DateHelper.MINUTE_SECONDS;
        if (now < activityInfo.getBeginTime() || now >= createTeamEndTime) {
            return false;
        }
        return true;
    }

    /**
     * 广播协助记录攻击信息
     *
     * @param list 需要广播的人员
     * @param team
     */
    public void broadcastHelpRecordAttackInfo(Collection<DunHuangShiKuUser> list, DunHuangShiKuTeam team) {
        // 广播当前队伍的协助
        Map<Long, DunHuangShiKuHelpRecordData> recordDataMap = getHelpRecordDataMap(team);
        for (DunHuangShiKuUser item : list) {
            if (item.inActivity) {
                DunHuangShiKuProto.BroadcastDunHuangShiKuHelpRecordAttackInfoEntity.Builder builder = DunHuangShiKuProto.BroadcastDunHuangShiKuHelpRecordAttackInfoEntity.newBuilder();
                for (DunHuangShiKuHelpRecordData recordData : recordDataMap.values()) {
                    DunHuangShiKuProto.DunHuangShiKuHelpRecordAttackInfoEntity.Builder attackInfo = DunHuangShiKuProto.DunHuangShiKuHelpRecordAttackInfoEntity.newBuilder();
                    attackInfo.setRecordId(recordData.getId());
                    DunHuangShiKuAttackInfo dunHuangShiKuAttackInfo = recordData.getHelpAttackMap().get(item.baseInfo.getUserId());
                    if (dunHuangShiKuAttackInfo != null) {
                        attackInfo.setTime(dunHuangShiKuAttackInfo.getAttackTime());
                    }
                    builder.addHelpRecordAttackInfos(attackInfo);
                }
                MessageHelper.sendPacket(item.baseInfo.getServerId(), item.baseInfo.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DUN_HUANG_SHI_KU_BROADCAST_HELP_ATTACK_INFO, builder));
            }
        }
    }

    /**
     * 尝试移除标记
     */
    public void attemptRemoveCurHelpRecord(DunHuangShiKuUser attacker, long targetId, boolean isReceived) {
        if (attacker.currentHelpRecordData == null) {
            return;
        }
        if (attacker.currentHelpRecordData.getTargetId() == targetId) {
            attacker.currentHelpRecordData.setKilledUserId(attacker.baseInfo.getUserId());
            attacker.currentHelpRecordData.setIsReceived(isReceived);
            attacker.currentHelpRecordData = null;
        }
    }


    public boolean reloadConfig() {
        return true;
    }

    public boolean reloadData() {
        return true;
    }

    /**
     * 获取需要获取活跃玩家的区服集合
     * 展示期第一天就获取 活跃玩家数据
     *
     * @return
     */
    public List<Long> getNeedSynActiveUserInfo() {
        List<Long> serverList = new ArrayList<>();
        int now = DateHelper.getCurrentSecond();
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        if (activityInfo == null) {
            return serverList;
        }
        long synTime = activityInfo.getBeginTime() + DUNHUANGSHIKU_DAILY_OPEN_TIME * DateHelper.HOUR_SECONDS;
        if (now < synTime || now >= activityInfo.getEndTime()) {
            return serverList;
        }
        if (npcBloodMap.size() != 0) {
            return serverList;
        }
        UnionActivityGroup groupData = Cross2UnionActivityGroupMgr.getGroupData(activityId, groupId);
        if (groupData == null) {
            return serverList;
        }
        for (Long serverId : groupData.getServerSet()) {
            if (!allUserBloodMap.containsKey(serverId)) {
                serverList.add(serverId);
            }
        }
        return serverList;
    }

    protected synchronized void receiveActiveUserInfo(long serverId, List<DunHuangShiKuProto.DunHuangShiKuActiveUserInfo> activeUserInfoList) {
        List<DunHuangShiKuUserBloodInfo> tempActiveUserInfoList = new ArrayList<>();
        for (DunHuangShiKuProto.DunHuangShiKuActiveUserInfo item : activeUserInfoList) {
            tempActiveUserInfoList.add(new DunHuangShiKuUserBloodInfo(item.getUserId(), serverId, item.getPatronsTotalAbility()));
        }
        allUserBloodMap.put(serverId, tempActiveUserInfoList);
        // 尝试刷新npc 血量
        refreshNpcBlood(false);
    }

    public int getActivityId() {
        return activityId;
    }

    public Map<Integer, DunHuangShiKuNpcBloodData> getNpcBloodMap() {
        return npcBloodMap;
    }
    public int adminChangeTeamName(int teamId, String teamName){
        DunHuangShiKuTeam teamData = teamMap.get(teamId);
        if(null == teamData){
            return GameErrorCode.E_DUN_HUANG_SHI_KU_TEAM_NO_EXIST;
        }
        teamData.baseInfo.setName(teamName);
        return 0;
    }

    public JSONObject adminQueryTeamData(long userId){
        JSONObject dataObj = new JSONObject();
        DunHuangShiKuUser userData = userMap.get(userId);
        if(null != userData) {
            int teamId = 0;
            if(null != userData.baseInfo){
                teamId = userData.baseInfo.getTeamId();
            }
            String teamName = "";
            DunHuangShiKuTeam teamData = teamMap.get(teamId);
            if (null != teamData) {
                teamName = teamData.baseInfo.getName();
            }
            dataObj.put("teamId", teamId);
            dataObj.put("teamName", teamName);
        }
        return dataObj;
    }

    public int getDUNHUANGSHIKU_ACTIVE_DAYS() {
        return DUNHUANGSHIKU_ACTIVE_DAYS;
    }

    public int getGroupId() {
        return groupId;
    }
}
